/**
 * @file nst_msg.c
 * @brief 通用消息队列实现（无锁环形缓冲区）
 * @date 2025-11-03
 */

#include "nst_msg.h"
#include <string.h>

/**
 * @brief 初始化消息队列
 */
void nst_msg_init(nst_msg_queue_t *queue, const char *name, uint8_t *buffer,
                  uint16_t element_size, uint16_t queue_size)
{
    strncpy(queue->name, name, NST_MSG_NAME_LEN - 1);
    queue->name[NST_MSG_NAME_LEN - 1] = '\0';
    queue->buffer = buffer;
    queue->element_size = element_size;
    queue->queue_size = queue_size;
    queue->head = 0;
    queue->tail = 0;
}

/**
 * @brief 非阻塞入队
 */
bool nst_msg_enqueue(nst_msg_queue_t *queue, const void *msg)
{
    /* 关闭全局中断保护临界区 */
    __disable_irq();

    uint16_t next_head = (queue->head + 1) % queue->queue_size;
    if (next_head == queue->tail)
    {
        __enable_irq();
        return false; /* 队列已满 */
    }

    uint8_t *dest = queue->buffer + (queue->head * queue->element_size);
    memcpy(dest, msg, queue->element_size);
    queue->head = next_head;

    __enable_irq();
    return true;
}

/**
 * @brief 非阻塞出队
 */
bool nst_msg_dequeue(nst_msg_queue_t *queue, void *msg)
{
    __disable_irq();

    if (queue->head == queue->tail)
    {
        __enable_irq();
        return false; /* 队列为空 */
    }

    const uint8_t *src = queue->buffer + (queue->tail * queue->element_size);
    memcpy(msg, src, queue->element_size);
    queue->tail = (queue->tail + 1) % queue->queue_size;

    __enable_irq();
    return true;
}

/**
 * @brief 检查队列是否为空
 */
bool nst_msg_is_empty(const nst_msg_queue_t *queue)
{
    return (queue->head == queue->tail);
}

/**
 * @brief 检查队列是否已满
 */
bool nst_msg_is_full(const nst_msg_queue_t *queue)
{
    return ((queue->head + 1) % queue->queue_size == queue->tail);
}

/**
 * @brief 获取队列剩余空间
 */
uint16_t nst_msg_remaining(const nst_msg_queue_t *queue)
{
    return (queue->queue_size - 1) -
           ((queue->head - queue->tail + queue->queue_size) % queue->queue_size);
}

/******************************** 文件结束 *********************************/
